package frog.lazy.framework.datasource.handler;

import frog.lazy.framework.core.mybatis.ExtendPO;
import frog.lazy.framework.core.tools.BeanUtils;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Properties;

@Intercepts(value = {
        @Signature(type = Executor.class, method = CommonSqlInterceptor.UPDATE_METHOD, args = {MappedStatement.class, Object.class})
})
public class CommonSqlInterceptor implements Interceptor {
    public static final String UPDATE_METHOD = "update";

    private final String CREATOR_FIELD = "creator";
    private final String CREATED_FIELD = "created";
    private final String UPDATER_FIELD = "updater";
    private final String UPDATED_FIELD = "updated";

    @Resource
    private frog.lazy.framework.datasource.provider.ICreatedAndUpdateProvider ICreatedAndUpdateProvider;

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        MappedStatement ms = (MappedStatement) invocation.getArgs()[0];
        SqlCommandType commandType = ms.getSqlCommandType();
        Object parameter = invocation.getArgs()[1];

        String methodName = invocation.getMethod().getName();

        ExtendPO po = ICreatedAndUpdateProvider.getExtendPO();
        String creator = po.getCreator();
        String updater = po.getUpdater();
        if(parameter instanceof ExtendPO) {
            if(methodName.equals(UPDATE_METHOD) && SqlCommandType.INSERT.equals(commandType)){
                BeanUtils.setFieldValue(parameter, CREATOR_FIELD, creator);
                BeanUtils.setFieldValue(parameter, CREATED_FIELD, LocalDateTime.now());
            }
            BeanUtils.setFieldValue(parameter, UPDATER_FIELD, updater);
            BeanUtils.setFieldValue(parameter, UPDATED_FIELD, LocalDateTime.now());
        }
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object o) {
        try{
            return Plugin.wrap(o, this);
        }catch (Exception e) {
            e.printStackTrace();
            return o;
        }
    }

    @Override
    public void setProperties(Properties properties) {

    }
}
